package com.gzx.plugin.fin.tech.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.gzx.plugin.fin.tech.cache.GzxFinTechDataManager;
import com.gzx.plugin.fin.tech.cache.TenantCacheManager;
import com.gzx.plugin.fin.tech.consts.GzxFinTechJudgeTypeConstant;
import com.gzx.plugin.fin.tech.dto.GzxFinTechBacktrackReqDTo;
import com.gzx.plugin.fin.tech.entity.GzxFinTechRecord;
import com.gzx.plugin.fin.tech.entity.GzxFinTechTenant;
import com.gzx.plugin.fin.tech.enums.GzxFinTechErrorEnum;
import com.gzx.plugin.fin.tech.service.GzxFinTechRecordService;
import com.gzx.plugin.fin.tech.service.GzxFinTechService;
import com.gzx.plugin.fin.tech.utils.ScoreUtil;

import cn.hutool.core.collection.CollUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import vip.xiaonuo.common.consts.IntConstant;
import vip.xiaonuo.common.util.CommonDateUtil;
import vip.xiaonuo.common.util.CommonIpAddressUtil;

@Slf4j
@Service("finTechService")
@RequiredArgsConstructor
public class GzxFinTechServiceImpl implements GzxFinTechService {

    private final GzxFinTechDataManager finTechDataManager;

    private final TenantCacheManager tenantCacheManager;
    private final GzxFinTechRecordService finTechRecordService;
    

    @Override
    public String forwardScoring(String reqBody, HttpServletRequest httpServletRequest) {
        long startTime = System.currentTimeMillis();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        log.info("获取评分,{}:{}", uuid, reqBody);
        try {
            Map<String, List<String>> reqMap = JSONObject.parseObject(reqBody, Map.class);
            List<String> phoneList = reqMap.containsKey("phone") ? reqMap.get("phone") : new ArrayList<>();
            List<String> cardIdList = reqMap.containsKey("cardId") ? reqMap.get("cardId") : new ArrayList<>();
            int totalCount = phoneList.size() + cardIdList.size();
            if (totalCount > IntConstant.VALUE_2000) {
                return buildErrorResponse(GzxFinTechErrorEnum.TOTAL_COUNT_ERROR);
            }
            JSONObject result = new JSONObject();
            GzxFinTechTenant finTechTenant = tenantCacheManager.getCurrentTenant();
            if (CollUtil.isNotEmpty(phoneList)) {
                JSONObject phoneResults = new JSONObject();
                for (String phone : phoneList) {
                    int score = 0;
                    if (GzxFinTechJudgeTypeConstant.MONTH.equals(finTechTenant.getJudgeType())) {
                        score = ScoreUtil.continuousScore(null, finTechDataManager.getFinTechByPhone(phone));
                    }
                    if (GzxFinTechJudgeTypeConstant.YEAR.equals(finTechTenant.getJudgeType())) {
                        score = ScoreUtil.discreteScore(null, finTechDataManager.getFinTechByPhone(phone));
                    }
                    phoneResults.put(phone, score);
                }
                result.put("phoneScores", phoneResults);
            }
            if (CollUtil.isNotEmpty(cardIdList)) {
                JSONObject cardIdResults = new JSONObject();
                for (String cardId : cardIdList) {
                    int score = 0;
                    if (GzxFinTechJudgeTypeConstant.MONTH.equals(finTechTenant.getJudgeType())) {
                        score = ScoreUtil.continuousScore(null, finTechDataManager.getFinTechByCardId(cardId));
                    }
                    if (GzxFinTechJudgeTypeConstant.YEAR.equals(finTechTenant.getJudgeType())) {
                        score = ScoreUtil.discreteScore(null, finTechDataManager.getFinTechByCardId(cardId));
                    }
                    cardIdResults.put(cardId, score);
                }
                result.put("cardIdScores", cardIdResults);
            }
            result.put("requestId", uuid);
            result.put("count", totalCount);
            saveRecord(uuid, totalCount, httpServletRequest);
            log.info("{}本次耗时：{}", uuid, System.currentTimeMillis() - startTime);
            return buildSuccessResponse(result);
        } catch (Exception e) {
            log.error("{}获取评分异常", uuid, e);
            return buildErrorResponse(GzxFinTechErrorEnum.SYS_ERROR);
        } finally {
            tenantCacheManager.clearCurrentTenant();
        }
    }

    /**
     * 回溯评分
     *
     * @param reqBody
     * @param httpServletRequest
     * @return
     */
    @Override
    public String backtrackScoring(String reqBody, HttpServletRequest httpServletRequest) {
        long startTime = System.currentTimeMillis();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        log.info("获取评分,{}:{}", uuid, reqBody);
        try {
            Map<String, List<GzxFinTechBacktrackReqDTo>> reqMap = JSONObject.parseObject(
                    reqBody,
                    new TypeReference<Map<String, List<GzxFinTechBacktrackReqDTo>>>() {
                    });
            List<GzxFinTechBacktrackReqDTo> phoneList = reqMap.getOrDefault("phone", new ArrayList<>());
            List<GzxFinTechBacktrackReqDTo> cardIdList = reqMap.getOrDefault("cardId", new ArrayList<>());
            int totalCount = phoneList.size() + cardIdList.size();
            if (totalCount > IntConstant.VALUE_2000) {
                return buildErrorResponse(GzxFinTechErrorEnum.TOTAL_COUNT_ERROR);
            }
            JSONObject result = new JSONObject();
            if (CollUtil.isNotEmpty(phoneList)) {
                JSONObject phoneResults = new JSONObject();
                for (GzxFinTechBacktrackReqDTo phone : phoneList) {
                    phoneResults.put(phone.getId(), ScoreUtil.discreteScore(phone.getDate(), finTechDataManager.getBacktrackByPhone(phone.getId())));
                }
                result.put("phoneScores", phoneResults);
            }
            if (CollUtil.isNotEmpty(cardIdList)) {
                JSONObject cardIdResults = new JSONObject();
                for (GzxFinTechBacktrackReqDTo cardId : cardIdList) {
                    cardIdResults.put(cardId.getId(), ScoreUtil.discreteScore(cardId.getDate(), finTechDataManager.getBacktrackCardId(cardId.getId())));
                }
                result.put("cardIdScores", cardIdResults);
            }
            result.put("requestId", uuid);
            result.put("count", totalCount);
            log.info("{}本次耗时：{}", uuid, System.currentTimeMillis() - startTime);
            return buildSuccessResponse(result);
        } catch (Exception e) {
            log.error("{}获取评分异常", uuid, e);
            return buildErrorResponse(GzxFinTechErrorEnum.SYS_ERROR);
        } finally {
            tenantCacheManager.clearCurrentTenant();
        }
    }

    private void saveRecord(String requestId, int totalCount, HttpServletRequest httpServletRequest) {
        String apiKey = httpServletRequest.getHeader("apiKey");
        String apiSecret = httpServletRequest.getHeader("apiSecret");
        String timestamp = httpServletRequest.getHeader("timestamp");
        String nonce = httpServletRequest.getHeader("nonce");
        String signature = httpServletRequest.getHeader("signature");
        String clientIp = CommonIpAddressUtil.getIp(httpServletRequest);
        GzxFinTechRecord finTechRecord = new GzxFinTechRecord();
        finTechRecord.setApiKey(apiKey);
        finTechRecord.setApiSecret(apiSecret);
        finTechRecord.setTimestamp(timestamp);
        finTechRecord.setNonce(nonce);
        finTechRecord.setSignature(signature);
        finTechRecord.setClientIp(clientIp);
        finTechRecord.setRequestId(requestId);
        finTechRecord.setTotalCount(totalCount);
        finTechRecord.setCreateTime(CommonDateUtil.getCurrentTimeStr());
        finTechRecordService.saveSingleRecord(finTechRecord); 
    }
}
